package com.zj.wanandroid.ui.page.login

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.zj.wanandroid.data.http.HttpResult
import com.zj.wanandroid.data.http.HttpService
import com.zj.wanandroid.utils.AppUserUtil
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import javax.inject.Inject

// 使用Hilt依赖注入框架标记ViewModel
@HiltViewModel
class LoginViewModel @Inject constructor(
    private var service: HttpService  // 注入网络服务接口
) : ViewModel() {

    // 🔹 视图状态管理（使用Compose的mutableStateOf实现响应式状态）
    var viewStates by mutableStateOf(LoginViewState())  // 初始化默认状态
        private set  // 限制外部直接修改状态，确保状态更新的可控性

    // 🔹 事件总线（使用Kotlin的Channel实现一次性事件传递）
    private val _viewEvents = Channel<LoginViewEvent>(Channel.BUFFERED)  // 创建缓冲通道
    val viewEvents = _viewEvents.receiveAsFlow()  // 将通道转换为Flow，供UI层观察

    // 🔹 分发视图操作的核心方法
    fun dispatch(action: LoginViewAction) {
        when (action) {  // 根据操作类型分发处理逻辑
            is LoginViewAction.Login -> login()  // 处理登录操作
            is LoginViewAction.ClearAccount -> clearAccount()  // 清除账户输入
            is LoginViewAction.ClearPassword -> clearPassword()  // 清除密码输入
            is LoginViewAction.UpdateAccount -> updateAccount(action.account)  // 更新账户输入
            is LoginViewAction.UpdatePassword -> updatePassword(action.password)  // 更新密码输入
        }
    }

    // 🔹 登录业务逻辑处理（网络请求 + 状态更新）
    private fun login() {
        viewModelScope.launch {  // 在ViewModel作用域内启动协程
            flow {  // 构建数据流
                // 发起登录网络请求，传递账户和密码（去除前后空格）
                emit(service.login(viewStates.account.trim(), viewStates.password.trim()))
            }.map { response ->  // 处理网络响应
                if (response.errorCode == 0) {  // 请求成功
                    if (response.data != null) {  // 数据有效
                        HttpResult.Success(response.data!!)  // 包装成功结果
                    } else {  // 数据无效
                        throw Exception("服务器返回空数据")  // 抛出异常
                    }
                } else {  // 请求失败
                    throw Exception(response.errorMsg)  // 抛出错误信息
                }
            }.onEach { result ->  // 处理成功结果
                AppUserUtil.onLogin(result.result)  // 更新全局用户状态
                _viewEvents.send(LoginViewEvent.PopBack)  // 发送返回事件
            }.catch { error ->  // 捕获异常
                _viewEvents.send(LoginViewEvent.ErrorMessage(error.message ?: "未知错误"))  // 发送错误事件
            }.collect()  // 收集数据流，启动流程
        }
    }

    // 🔹 清除账户输入
    private fun clearAccount() {
        viewStates = viewStates.copy(account = "")  // 创建新状态实例，清空账户
    }

    // 🔹 清除密码输入
    private fun clearPassword() {
        viewStates = viewStates.copy(password = "")  // 创建新状态实例，清空密码
    }

    // 🔹 更新账户输入
    private fun updateAccount(account: String) {
        viewStates = viewStates.copy(account = account)  // 创建新状态实例，更新账户
    }

    // 🔹 更新密码输入
    private fun updatePassword(password: String) {
        viewStates = viewStates.copy(password = password)  // 创建新状态实例，更新密码
    }
}

// 🔹 视图状态数据类（包含账户/密码/登录状态）
data class LoginViewState(
    val account: String = "",  // 账户输入框内容
    val password: String = "",  // 密码输入框内容
    val isLogged: Boolean = false  // 用户是否已登录
)

// 🔹 一次性事件定义（密封类实现类型安全）
sealed class LoginViewEvent {
    object PopBack : LoginViewEvent()  // 返回上一界面事件
    data class ErrorMessage(val message: String) : LoginViewEvent()  // 显示错误信息事件
}

// 🔹 视图操作类型定义（密封类实现操作分类）
sealed class LoginViewAction {
    object Login : LoginViewAction()  // 登录操作
    object ClearAccount : LoginViewAction()  // 清除账户操作
    object ClearPassword : LoginViewAction()  // 清除密码操作
    data class UpdateAccount(val account: String) : LoginViewAction()  // 更新账户操作
    data class UpdatePassword(val password: String) : LoginViewAction()  // 更新密码操作
}